#!/usr/bin/env python
# -*- coding: utf-8 -*-

import threading,os
from options import Options
import netfinitylib
from common import VERSION,basepath
from prefview import PrefView
from prefcontroller import PrefController

try:
	from kiwi.controllers import BaseController
except ImportError:
	print "Installa python-kiwi"
	raise SystemExit

class MainController(BaseController):

	#classe che fa da interfaccia fra la grafica e Client
	class ClientThread(threading.Thread):
		SENDMSG,GETADDRESSBOOK,STARTMESSAGE = range(3)
		
		view = None
		client = None
		job = "" # (0) sendMsg | (1) getAddressBook | (2) startMessage
		args = ()
		# (0) args:
		#  (dest,text)
		# (1) args:
		#  (namedefaultgroup,)
		# (2) args:
		#  ()
		
		def __init__(self,view,client,job,args):
			threading.Thread.__init__(self)
			self.setDaemon(True)
			
			self.view = view
			self.client = client
			self.job = job
			self.args = args
		def run(self):
			#print "I'm a thread"
			if self.job == self.SENDMSG:
				dest,text = self.args
				
				if len(text)>self.view.MAXLENMSG:
					s = text[:self.view.MAXLENMSG] + "..."
				else:	s = text
				self.view.log_add_line('Invio messaggio in corso...')
				res = self.client.sendMsg(dest,text).partition(":")[2]
				#ignoro il codice di errore
				
				
				
				self.view.log_add_line('%s [%s]' % ("temp",s))
				
			elif self.job == self.GETADDRESSBOOK:
				ab = self.client.getAddressBook()
				self.view.draw_addressbook(ab,self.args[0])
				self.view.log_add_line('Rubrica letta con successo!',True)
			elif self.job == self.STARTMESSAGE:
				text,info = self.client.startMessage()
				self.view.buf.set_text(text)
				self.view.log_add_line('Messaggio di avvio caricato',True)
			else:
				print "non so che fare"

	options = None
	client = None
	replacedic = {}
	
	def __init__(self,view):
		BaseController.__init__(self,view)
		self.view.set_default_focus()
		
		if os.name=='posix':
			self.options = Options(basepath()+'/netfinity.conf')
		else:
			self.options = Options()
		self.client = netfinitylib.Client(self.options['u'][0],self.options['p'][0],VERSION)
		
		#carica il dizionario di sostituzione
		if 'replacechar' in self.options():
			for opt in self.options['replacechar']:
				self.replacedic[opt[0]] = opt[1:]
		
		#nome del gruppo di default della rubrica
		if 'namedefaultgroup' in self.options():
			nomegruppodefault = self.options['namedefaultgroup'][0]
		else:
			nomegruppodefault = ""
		#caricamento rubrica
		clientThread = self.ClientThread(self.view,self.client,self.ClientThread.GETADDRESSBOOK,(nomegruppodefault,))
		clientThread.start()#avvia il thread
		
		#caricamento start message
		clientThread = self.ClientThread(self.view,self.client,self.ClientThread.STARTMESSAGE,())
		clientThread.start()#avvia il thread
	#Eventi#
	
	#toolbar
	def on_tool_resettext__clicked(self,*args):
		self.view.clear_text()
		self.view.set_default_focus()
	def on_tool_resetall__clicked(self,*args):
		self.view.clear()
	def on_tool_send__clicked(self,*args):
		text = self.view.get_text()
		if not text:
			self.view.log_add_line("Scrivere il testo del messaggio")
			return
		
		storedest =  self.view.destnotebook.get_nth_page(self.view.get_n_dest_list()).get_children()[0].get_model()
		i = storedest.get_iter_root()
		nums = []
		while i:
			nums.append(storedest.get_value(i,1)) #prendo solo il numero
			i = storedest.iter_next(i)
		if not nums:
			self.view.log_add_line("Non è stato selezionato nessun destinatario")
			return
		#non devono esserci numeri doppi
		nums_unique = []
		for num in nums:
			if not num in nums_unique:
				nums_unique.append(num)
		nums = ",".join(nums_unique)
		
		clientThread = self.ClientThread(self.view,self.client,self.ClientThread.SENDMSG,(nums,text))
		clientThread.start()#avvia il thread
	def on_tool_config__clicked(self,*args):
		#dovrei impedire alla finestra principale di prendere il focus qnd
		#questa e` aperta
		prefview = PrefView()
		prefcontroller = PrefController(prefview)
		prefview.show()
	def on_tool_about__clicked(self,*args):
		self.view.show_about()
	#
	def on_buf__insert_text(self,buf,textend,text,length,*args):
		#print text,length
		changed = False
		newtext = ""
		for c in text:
			if c in self.replacedic:
				changed = True
				newtext += self.replacedic[c]
			else:
				newtext += c
		#print changed,newtext
		if changed:
			#sostituisco il testo
			textstart = textend.copy()
			textstart.backward_cursor_positions(length)
			buf.delete(textstart,textend)
			buf.insert_at_cursor(newtext)
		if buf.get_char_count()>360:
			text = buf.get_text(buf.get_start_iter(),buf.get_end_iter())
			buf.set_text(text[:360])
		#ora dovrei settare la label "n/m"
	#Eventi rubrica
	#def on_abview__cursor_changed(self,*args):
	#	print "clicked"
	#def on_abview__test_collapse_row(self,*args):
	#	print "signal>"
	#def on_abview__test_expand_row(self,*args):
	#	print "signal<"
	def on_abview__row_activated(self,abview,path,*args): #doppio click
		#def on_abview__cursor_changed(self,*args): #click (cacchio manca il path)
		#print "row_activated",abview.rowexpanded
		abstore = self.view.abstore #tanto per accorciare un po'
		
		#gestisco qui l'espanzione (al massimo un gruppo per volta)
		if len(path) == 1:
			#e` un gruppo
			if abview.row_expanded(path):
				abview.collapse_row(path[0])
				abview.rowexpanded = -1
			else:
				if abview.rowexpanded>=0:
					abview.collapse_row(self.view.abview.rowexpanded)
				abview.expand_to_path(path)
				abview.rowexpanded = path[0]
		#else:
		#	#e` un figlio
		#	treeiter = abstore.get_iter(path)
		#	nome,numero,checkbox = abstore.get(treeiter,0,4,self.view.get_n_dest_list()+5)
		#	print nome,numero,checkbox,"("+str(self.view.get_n_dest_list())+")"
		#	#abstore.set_value(treeiter,2,True)
		
		#codice inutile
		#treeiter = abstore.get_iter(path)
		#while treeiter:
		#	print abstore.get_path(treeiter)
		#	soniter = abstore.iter_children(treeiter)
		#	while soniter:
		#		print "\t",.abstore.get_path(soniter)
		#		soniter = abstore.iter_next(soniter)
		#	treeiter = abstore.iter_next(treeiter)
	def on_destnotebook__switch_page(self,dest,page,page_num,*args):
		#print "switch-page",page_num
		page_num = int(page_num)
		if page_num<5:
			#rubrica valida
			self.view.set_destlist(page_num)
	def on_silixlinkbutton__clicked(self,button,*args):
		os.system("firefox "+button.get_uri())
		#e chi non usa FF? :(
	def on_maillinkbutton__clicked(self,button,*args):
		self.view.log_add_line("Non so gestire gli indirizzi email, copiatelo!")
	#toggle button della rubrica
	def on_togglebuttons__toggled(self, cell, path, *args):
		abstore = self.view.abstore
		n_dest_list = self.view.get_n_dest_list()
		storedest =  self.view.destnotebook.get_nth_page(n_dest_list).get_children()[0].get_model()
		
		#questi dovrebbero essere metodi della View
		def append(p):
			row = abstore[p]
			parentrow = abstore[path.partition(":")[0]]
			#  (0)        (1)
			if p==path or not row[n_dest_list+5]:
				#condizione complessa...
				# 0: sto appendendo un figlio (singolo)
				# 1: seleziono un gruppo e il figlio non e` ancora stato aggiunto
				storedest.append([row[0]+" ["+parentrow[0]+"]",row[4]]) # ['nome [gruppo]','numero']
		def remove(p):
			row = abstore[p]
			parentrow = abstore[path.partition(":")[0]]
			key = row[0]+" ["+parentrow[0]+"]"
			i = storedest.get_iter_root()
			while i:
				#anche la remove() la faccio per 'nome [gruppo]'
				if key == storedest.get_value(i,0):
					storedest.remove(i)
					break
				i = storedest.iter_next(i)
		
		#inverto il togglebutton
		i = abstore.get_iter(path)
		active = not abstore.get_value(i, n_dest_list+5)
		abstore.set_value(i,n_dest_list+5,active)
		
		if not path.partition(":")[1]:
			#padre
			#metto allo stesso valore tutti i figli
			iterc = abstore.iter_children(i)
			while iterc:
				if active:
					append(":".join([str(i) for i in abstore.get_path(iterc)]))
					#converto il path da (tupla,) a "stringa"
					#(il massimo dello spreco di risorse :) )
				else:	remove(":".join([str(i) for i in abstore.get_path(iterc)]))
					#come prima..
				#devo farlo dopo l'append
				abstore.set_value(iterc,n_dest_list+5,active)
				iterc = abstore.iter_next(iterc)
		elif not active:
			# un figlio che viene disattivato
			#disattivo il padre
			abstore.set_value(abstore.iter_parent(i),n_dest_list+5,False) #non dovrebbe essere False, ma inconsistente
			remove(path)
		else:
			# un figlio che viene attivato
			append(path)
	##

